﻿using Microsoft.Extensions.Configuration;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.Common;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.ElectronicSign;
using NP.BPMReportPlatform.Entities.BPM_Business.HYT;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.HYT.Dto;
using NP.BPMReportPlatform.Utils;
using NP.Enterprise.Utils.Http;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using NP.BPMReportPlatform.Contract.Dtos;
using NP.BPMReportPlatform.Entities.BPM_Business.Contract;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using MT.Enterprise.Utils.MultipartRequestHelper;
using NP.BPMReportPlatform.Utilities;
using NP.BPMReportPlatform.Reports.OrderMaterialDetail.Dtos;
using System.Linq;
using NP.BPMReportPlatform.Entities.BPM_Business.Reports;
using System.Security.Cryptography;
using Volo.Abp.Users;
using DocumentFormat.OpenXml.Office2010.Excel;

namespace NP.BPMReportPlatform.Contract
{
    public class ContractESignService : BPMReportPlatformAppService, IContractESignService
    {
        private readonly SqlSugarClient _dbBussiness;
        private readonly SqlSugarClient _dbPlatform;
        private readonly IESService _eSService;        
        private readonly IConfiguration _configuration;
        private readonly ICommonService _commonService;
        public ContractESignService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp, INPRestHttpHelper nPRestHttp, IESService eSService,
            IConfiguration configuration, ICommonService commonService)
        {
            _dbBussiness = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _eSService = eSService;
            _configuration = configuration;
            _commonService = commonService;
        }

        public async Task<PagedResultDto<ContractESignDto>> GetAllAsync(ContractESignInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            //返回结果
            return new PagedResultDto<ContractESignDto>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<ContractESignDto>> ExportAsync(ContractESignInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        /// <summary>
        /// 获取Queryable(报表展现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<ContractESignDto> GetQueryable(ContractESignInput input)
        {
            //var currentWorkNumber = CurrentUser != null && CurrentUser.UserName != null ? CurrentUser.UserName : string.Empty;
            //var userCodes = _commonService.GetUserByRoleFilter(currentWorkNumber, RelationshipTypeEnum.ER);
            //userCodes = userCodes != null && userCodes.Count > 0 ? userCodes : new List<string>() { "-1" };
            //bool isAdmin = userCodes.Contains("9999999999");
            var listQueryable = _dbPlatform.Queryable<ContractESignFlow, UserExtension, Users>(
                    (x, u, us) => new JoinQueryInfos(JoinType.Left, x.WorkNumber == u.Sapemployeeid, JoinType.Left, x.WorkNumber == us.WorkNumber))
                //.WhereIF(!isAdmin, (x, u, us) => SqlFunc.ContainsArray(userCodes, x.WorkNumber))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, x => x.UploadTime >= input.StartCreationTime && x.UploadTime <= input.EndCreationTime)
                .WhereIF(!string.IsNullOrWhiteSpace(input.UserName), (x, u, us) => u.Name.Equals(input.UserName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.WorkNumber), (x, u, us) => x.WorkNumber.Equals(input.WorkNumber))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Region), (x, u, us) => u.RegionName.Contains(input.Region))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Department), (x, u, us) => u.Orgname.Contains(input.Department))
                .WhereIF(input.IsIncomplete != null, (x, u, us) => SqlFunc.IsNullOrEmpty(x.UserName) || SqlFunc.IsNullOrEmpty(x.Department) || SqlFunc.IsNullOrEmpty(x.Region))
                .Select((x, u, us) => new ContractESignDto
                {
                    Id = x.Id,
                    WorkNumber = x.WorkNumber,
                    FileName = x.FileName,
                    AddTime = x.AddTime,
                    Region = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(u.RegionName), x.Region, u.RegionName),
                    Department = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(us.FullPathText), x.Department, us.FullPathText),
                    UserName = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(u.Name), x.UserName, u.Name),
                    SignStatus = x.SignStatus,
                    UploadTime = x.UploadTime,
                    UpoladTimeStr = x.UploadTime != null ? x.UploadTime.Value.ToString(DateFormatHelper.DateTimeFormat) : "",
                    SignFlowId = x.SignFlowId,
                }).OrderBy(x => x.AddTime, OrderByType.Desc);
            return listQueryable;
        }

        public async Task<ImportResultExt<ContractESignDto>> ImportAsync(List<ContractESignDto> data)
        {
            var rst = new ImportResultExt<ContractESignDto>
            {
                Data = data
            };

            var dataList = await _dbPlatform.Queryable<ContractESignFlow>().ToListAsync();
            var users = await _dbPlatform.Queryable<Users, UserExtension>((u, ue) => new JoinQueryInfos(
                JoinType.Inner, u.WorkNumber == ue.Sapemployeeid))
                .Select((u, ue) => new ContractESignDto {
                    WorkNumber = u.WorkNumber,
                    UserName = u.UserName,
                    Region = ue.RegionName,
                    Department = ue.Orgname
                }).ToListAsync();
            var updateList = new List<ContractESignFlow>();
            var insertList = new List<ContractESignFlow>();
            var currentUser = await _dbPlatform.Queryable<Users>().FirstAsync(x => x.WorkNumber == CurrentUser.UserName && x.Status == 1);
            var index = 2;
            foreach (var item in data)
            {
                if (string.IsNullOrEmpty(item.WorkNumber))
                {
                    rst.Exception = new Exception($"第{index}行，缺少工号");
                    break;
                }
                //if (string.IsNullOrEmpty(item.FileName))
                //{
                //    rst.Exception = new Exception($"第{index}行，缺少文件名称");
                //    break;
                //}
                //if (string.IsNullOrEmpty(item.SignStatus))
                //{
                //    rst.Exception = new Exception($"第{index}行，缺少签署状态");
                //    break;
                //}
                if (string.IsNullOrEmpty(item.SignFlowId))
                {
                    rst.Exception = new Exception($"第{index}行，缺少电子签ID");
                    break;
                }
                var user = users.FirstOrDefault(x => x.WorkNumber == item.WorkNumber);
                var model = dataList.FirstOrDefault(x => x.SignFlowId == item.SignFlowId);
                if (model != null)
                {
                    model.WorkNumber = item.WorkNumber;
                    model.FileName = item.FileName;
                    model.SignStatus = item.SignStatus;
                    model.SignFlowId = item.SignFlowId;
                    model.UserName = string.IsNullOrEmpty(user?.UserName) ? item.UserName : user?.UserName;
                    model.Region = string.IsNullOrEmpty(user?.Region) ? item.Region : user?.Region;
                    model.Department = string.IsNullOrEmpty(user?.Department) ? item.Department : user?.Department;
                    model.UpdateUser = currentUser?.WorkNumber ?? "";
                    model.UpdateUserName  = currentUser?.UserName ?? "";
                    model.UpdateTime = DateTime.Now;
                    model.UploadTime = DateTime.Now;
                    updateList.Add(model);
                }
                else
                {
                    var entity = new ContractESignFlow
                    {
                        Id = Guid.NewGuid().ToString(),
                        WorkNumber = item.WorkNumber,
                        FileName = item.FileName,
                        SignStatus = item.SignStatus,
                        SignFlowId = item.SignFlowId,
                        UserName = string.IsNullOrEmpty(user?.UserName) ? item.UserName : user?.UserName,
                        Region = string.IsNullOrEmpty(user?.Region) ? item.Region : user?.Region,
                        Department = string.IsNullOrEmpty(user?.Department) ? item.Department : user?.Department,
                        UploadTime = DateTime.Now,
                        AddUser = currentUser?.WorkNumber ?? "",
                        AddUserName = currentUser?.UserName ?? "",
                        AddTime = DateTime.Now
                    };
                    insertList.Add(entity);
                }

                index++;
            }

            if (!rst.HasError)
            {
                try
                {
                    _dbPlatform.BeginTran();

                    if (updateList.Any())
                    {
                        await _dbPlatform.Updateable(updateList).ExecuteCommandAsync();
                    }
                    if (insertList.Any())
                    {
                        await _dbPlatform.Insertable(insertList).ExecuteCommandAsync();
                    }

                    _dbPlatform.CommitTran();
                }
                catch (Exception ex)
                {
                    rst.Exception = new Exception(ex.Message);
                    _dbPlatform.RollbackTran();
                }
            }

            var resp = new ImportResultExt<ContractESignDto>()
            {
                Exception = rst.Exception,
                RowErrors = rst.RowErrors,
                TemplateErrors = rst.TemplateErrors
            };
            return resp;
        }

        public async Task<string> EditAsync(ContratEsignEditInput input)
        {
            var entity = await _dbPlatform.Queryable<ContractESignFlow>().FirstAsync(x => x.Id == input.Id);
            if (!string.IsNullOrEmpty(input.Id) && entity == null)
            {
                throw new Exception("数据未找到");
            }

            if (string.IsNullOrEmpty(input.WorkNumber))
            {
                throw new Exception("缺少工号");
            }
            if (string.IsNullOrEmpty(input.SignFlowId))
            {
                throw new Exception("缺少电子签ID");
            }

            var currentUser = await _dbPlatform.Queryable<Users>().FirstAsync(x => x.WorkNumber == CurrentUser.UserName && x.Status == 1);

            if (entity != null)
            {
                entity.WorkNumber = input.WorkNumber;
                entity.FileName = input.FileName;
                entity.SignStatus = input.SignStatus;
                entity.SignFlowId = input.SignFlowId;
                entity.UpdateUser = currentUser?.WorkNumber ?? "";
                entity.UpdateUserName = currentUser?.UserName ?? "";
                entity.UpdateTime = DateTime.Now;
                entity.UserName = input.UserName;
                entity.Region = input.Region;
                entity.Department = input.Department;
                var flag = await _dbPlatform.Updateable(entity).ExecuteCommandAsync();
                return flag > 0 ? "保存成功" : "保存失败";
            }
            else
            {
                entity = new ContractESignFlow
                {
                    Id = Guid.NewGuid().ToString(),
                    WorkNumber = input.WorkNumber,
                    FileName = input.FileName,
                    SignStatus = input.SignStatus,
                    SignFlowId = input.SignFlowId,
                    UploadTime = DateTime.Now,
                    AddUser = currentUser?.WorkNumber ?? "",
                    AddUserName = currentUser?.UserName ?? "",
                    AddTime = DateTime.Now,
                    UserName = input.UserName,
                    Region = input.Region,
                    Department = input.Department,
                };
                var flag = await _dbPlatform.Insertable(entity).ExecuteCommandAsync();
                return flag > 0 ? "保存成功" : "保存失败";
            }
        }

        public async Task Delete(string id)
        {
            var entity = await _dbPlatform.Queryable<ContractESignFlow>().FirstAsync(x => x.Id == id);
            if (entity != null)
            {
                await _dbPlatform.Deleteable(entity).ExecuteCommandAsync();
            }

            return;
        }

        public async Task<bool> IsAdmin()
        {
            var currentWorkNumber = CurrentUser != null && CurrentUser.UserName != null ? CurrentUser.UserName : string.Empty;
            var userCodes = _commonService.GetUserByRoleFilter(currentWorkNumber, RelationshipTypeEnum.ER);
            userCodes = userCodes != null && userCodes.Count > 0 ? userCodes : new List<string>() { "-1" };
            return userCodes.Contains("9999999999");
        }
    }
}
